﻿using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Reflection;
using System.Windows.Forms;
using System.Xml;
using McTools.Xrm.Connection.WinForms;
using SolutionExtender.Controls;
using McTools.Xrm.Connection;
using Microsoft.Xrm.Sdk;
using SolutionExtender.Interfaces;
using SolutionExtender.Plugins;

namespace SolutionExtender
{
    public sealed partial class MainForm : Form
    {
        #region Variables

        /// <summary>
        /// IOrganization service for Crm data access
        /// </summary>
        internal static IOrganizationService Service;

        /// <summary>
        /// Connection bar
        /// </summary>
        readonly CrmConnectionStatusBar _ccsb;

        /// <summary>
        /// Connection Manager
        /// </summary>
        readonly ConnectionManager _cManager;

        private readonly FormHelper _fHelper;

        /// <summary>
        /// Current step in the wizard
        /// </summary>
        private int _currentStep;

        /// <summary>
        /// List of connectors selected for export
        /// </summary>
        private List<IExportControl> _connectors;

        /// <summary>
        /// Selected items for export
        /// </summary>
        private XmlDocument _exportDoc;

        private readonly PluginManager _pManager;
        
        #endregion Variables

        #region Constructor

        /// <summary>
        /// Initializes a new instance of class MainForm
        /// </summary>
        public MainForm()
        {
            InitializeComponent();

            Text += string.Format(" ({0})",
                                           Assembly.GetExecutingAssembly().GetName().Version);

            _cManager = new ConnectionManager();
            _cManager.ConnectionSucceed += CManagerConnectionSucceed;
            _cManager.ConnectionFailed += CManagerConnectionFailed;
            _cManager.StepChanged += CManagerStepChanged;
            _cManager.RequestPassword += CManagerRequestPassword;
            _fHelper = new FormHelper(this, _cManager);

            _ccsb = new CrmConnectionStatusBar(_cManager, _fHelper) {BackColor = Color.White};
            Controls.Add(_ccsb);

            _pManager = new PluginManager();
            _pManager.LoadPlugins();
        }

        bool CManagerRequestPassword(object sender, RequestPasswordEventArgs e)
        {
            return _fHelper.RequestPassword(e.ConnectionDetail);
        }

        #endregion Constructor

        #region Connection Methods

        void CManagerStepChanged(object sender, StepChangedEventArgs e)
        {
            _ccsb.SetMessage(e.CurrentStep);
        }

        void CManagerConnectionFailed(object sender, ConnectionFailedEventArgs e)
        {
            _ccsb.SetMessage("Error: " + e.FailureReason);
            MessageBox.Show("Error: " + e.FailureReason, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            Service = null;
        }

        void CManagerConnectionSucceed(object sender, ConnectionSucceedEventArgs e)
        {
            Service = e.OrganizationService;

            _ccsb.SetConnectionStatus(true, e.ConnectionDetail);
            _ccsb.SetMessage(string.Empty);

            pnlConnection.Visible = false;
            pnlSteps.Visible = true;
            btnNext.Visible = true;

            var ctrl = new ActionSelectionControl();
            pnlSteps.Controls.Add(ctrl);
            _currentStep = 0;
        }

        #endregion Connection Methods

        #region Controls handlers

        private void BtnConnectClick(object sender, System.EventArgs e)
        {
            _fHelper.AskForConnection(null);
        }

        private void BtnNextClick(object sender, System.EventArgs e)
        {
            switch(_currentStep)
            {
                case 0:
                    {
                        var isExport = ((ActionSelectionControl) pnlSteps.Controls[0]).IsExport();

                        if(isExport)
                        {
                            pnlSteps.Controls.Clear();
                            pnlSteps.Controls.Add(new FeatureSelectionControl(Service, _pManager));
                            
                            _currentStep = 1;
                            
                            //btnPrevious.Visible = true;
                            btnReset.Visible = true;
                        }
                        else
                        {
                            var list = ((ActionSelectionControl) pnlSteps.Controls[0]).GetXmlNodeToImport();

                            if (list != null)
                            {
                                pnlSteps.Controls.Clear();
                                pnlSteps.Controls.Add(new ImportControl(list, _pManager, Service));

                                _currentStep = 100;

                                btnReset.Visible = true;
                                //btnPrevious.Visible = false;
                                btnNext.Visible = false;
                            }
                        }
                    }
                    break;
                case 1:
                    {
                        _connectors = ((FeatureSelectionControl)pnlSteps.Controls[0]).GetControlsToLoad();

                        if (_connectors != null)
                        {
                            var uControl = (UserControl) _connectors[_currentStep - 1];
                            uControl.Anchor = AnchorStyles.Left | AnchorStyles.Right 
                                                | AnchorStyles.Top | AnchorStyles.Bottom; 

                            pnlSteps.Controls.Clear();
                            pnlSteps.Controls.Add(uControl);
                            _currentStep = 2;

                            //btnPrevious.Visible = true;
                            btnReset.Visible = true;
                        }
                    }
                    break;
                default:
                    {
                        var settingsList = ((IExportControl) pnlSteps.Controls[0]).GetSelectedItems();

                        if (settingsList != null)
                        {
                            ApplySettings(settingsList);

                            if (_connectors.Count >= _currentStep)
                            {
                                pnlSteps.Controls.Clear();
                                pnlSteps.Controls.Add((UserControl)_connectors[_currentStep - 1]);
                                _currentStep += _currentStep + 1;

                                //btnPrevious.Visible = true;
                                btnReset.Visible = true;
                            }
                            else
                            {
                                pnlSteps.Controls.Clear();
                                pnlSteps.Controls.Add(new ExportControl(_exportDoc));
                                _currentStep += _currentStep + 1;

                                btnNext.Visible = false;
                                //btnPrevious.Visible = false;
                            }
                        }
                    }
                    break;
            }
        }

        private void BtnResetClick(object sender, System.EventArgs e)
        {
            _currentStep = 0;
            _exportDoc = null;

            //btnPrevious.Visible = false;
            btnReset.Visible = false;
            btnNext.Visible = true;

            pnlSteps.Controls.Clear();
            pnlSteps.Controls.Add(new ActionSelectionControl());
        }

        #endregion Controls handlers

        private void ApplySettings(XmlNodeList settingsList)
        {
            if(_exportDoc == null)
            {
                _exportDoc = new XmlDocument();
                _exportDoc.LoadXml("<Settings></Settings>");
            }

            if(settingsList.Count > 0)
            {
                var nodeName = settingsList[0].Name;
                var existingNodes = _exportDoc.SelectNodes("//" + nodeName);
                for(int i = existingNodes.Count - 1; i >= 0; i--)
                {
                    _exportDoc.DocumentElement.RemoveChild(existingNodes[i]);
                }
            }

            foreach (XmlNode settingsNode in settingsList)
            {
                var nodeToImport = _exportDoc.ImportNode(settingsNode, true);
                _exportDoc.DocumentElement.AppendChild(nodeToImport);
            }
        }

        #region Links Methods

        private void PbDonateClick(object sender, System.EventArgs e)
        {
            var url =
               string.Format(
                   "https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business={0}&lc={1}&item_name={2}&currency_code={3}&bn=PP%2dDonationsBF",
                   "tanguy92@hotmail.com",
                   "FR",
                   "Donation%20for%20MSCRM%20Tools%20-%20Solution%20Extender",
                   "EUR");

            Process.Start(url);
        }

        private void PbCommentClick(object sender, System.EventArgs e)
        {
            Process.Start("http://solutionextender.codeplex.com/discussions");
        }

        private void PbBugClick(object sender, System.EventArgs e)
        {
            Process.Start("http://solutionextender.codeplex.com/WorkItem/Create");
        }

        private void PbRateClick(object sender, System.EventArgs e)
        {
            Process.Start("http://solutionextender.codeplex.com/releases");
        }

        #endregion Links Methods

        private void PbNetworkClick(object sender, System.EventArgs e)
        {
            _fHelper.EditProxySettings(this, _cManager.ConnectionsList);
        }
    }
}
